package org.android.util;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import android.util.Log;

public class XBeanUtils {
	/**
	 * 通过Method 获取该set 或 get 方法的Method  所对应的字段的名称
	 * @param method
	 * @return     
	 */
	public static String getFieldNameFromMethod(Method method){
		String methodName=method.getName();
		methodName=methodName.substring(3);
		String FieldName =methodName.substring(0,1).toLowerCase()+methodName.substring(1);
		return FieldName;
	}
	/**
	 * 
	 */
	public static boolean isSetMethod(Method method){
		if(method.getName().startsWith("set")){
			return true;
		}
		return false;
	}
	/**
	 * 获取所有的get方法
	 * @param beanClass
	 * @return
	 */
	public static List<Method> getGetMethods(Class beanClass){
		
		List<Method> methods=new ArrayList<Method>();
		for(Method method:methods){
			String methodName=method.getName();
			if(methodName.startsWith("get")&&(!method.equals("getClass"))){
				methods.add(method);
			}
		}
		return methods;
	}
	/**
	 * 获取所有的set方法
	 * @param beanClass
	 * @return
	 */
	public static List<Method> getSetMethods(Class beanClass){
		
		List<Method> methods=new ArrayList<Method>();
		for(Method method:beanClass.getMethods()){
			String methodName=method.getName();
			if(methodName.startsWith("set")){
				methods.add(method);
			}
		}
		return methods;
	}
	/**
	 * 
	 * @param method
	 * @return
	 */
	public static boolean isGetMethod(Method method){
		String methodName=method.getName();
		if(methodName.startsWith("get")&&(!methodName.equals("getClass"))){
			return true;
		}
		return false;
	}
	/**
	 * 给我个类的类型和一个字段的名字， 我告诉你这个字段是什么类型
	 * 
	 * @param BeanClass
	 * @param key
	 * @return
	 */
	public static Class getPropertyType1(Class BeanClass, String key) {
		try {
			Field field = BeanClass.getDeclaredField(key);
			Class propertyType = field.getType();
			return propertyType;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 通过成员变量名获取该成员变量的类型，由于成员变量为私有的，所以需要通过Setter方法获取该方法的参数类型。来获取成员变量名
	 * 
	 * @param javaBeanClass
	 *            javaBean类型
	 * @param fieldName
	 *            成员变量名
	 * @return 成员变量的名称
	 */
	public static Class getPropertyType(Class javaBeanClass, String fieldName) {
		if (fieldName == null || fieldName.trim().length() <= 0) {
			return null;
		}
		String setName = "set" + fieldName.substring(0, 1).toUpperCase()
				+ fieldName.substring(1);
		Method[] allMethod = javaBeanClass.getMethods();
		for (Method method : allMethod) {
			if (method.getName().equals(setName)) {
				Class[] paramClass = method.getParameterTypes();
				if (paramClass == null || paramClass.length == 0
						|| paramClass.length > 1) {
					return null;
				}
				return paramClass[0];
			}
		}
		return null;
	}

	/**
	 * 根据给定的 设置bean里对应字段的值
	 * 
	 * @param bean
	 * @param key
	 * @param value
	 */
	public static void setProperty(Object bean, String key, Object value) {
		try {
			key = "set" + key.substring(0, 1).toUpperCase() + key.substring(1);
			Method setMethod = bean.getClass().getDeclaredMethod(key,
					value.getClass());
			setMethod.invoke(bean, value);

		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @param map
	 * @param beanClass
	 * @return
	 * @throws IllegalArgumentException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 * @throws UnsupportedEncodingException
	 */
	public static Object parseMapToJavaBean(Map<String, ?> map, Class beanClass)
			throws IllegalArgumentException, SecurityException,
			IllegalAccessException, InvocationTargetException,
			NoSuchMethodException, UnsupportedEncodingException {
		Object object = null;
		try {
			object = beanClass.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		// 获取所有表单名字
		Set<String> parameterNames = map.keySet();
		for (String pname : parameterNames) {

			Field[] fields = beanClass.getDeclaredFields();
			for (Field field : fields) {
				// 找到对应的字段
				if (field.getName().equals(pname)) {
					// 获得该字段的类型
					Class fieldType = field.getType();
					// 找到对应的set方法
					if (fieldType == String.class) {
						String value = (String) map.get(pname);
						beanClass.getMethod(createMethodName(pname),
								String.class).invoke(object, value);
					}
					if (fieldType == Boolean.class) {
						beanClass.getMethod(createMethodName(pname),
								Boolean.class).invoke(object,
								Boolean.parseBoolean((String) map.get(pname)));
					}
					if (fieldType == Integer.class) {
						beanClass.getMethod(createMethodName(pname),
								Integer.class).invoke(object,
								Integer.parseInt((String) map.get(pname)));
					}
					if (fieldType == Byte.class) {
						beanClass
								.getMethod(createMethodName(pname), Byte.class)
								.invoke(object,
										Byte.parseByte((String) map.get(pname)));
					}
					if (fieldType == Short.class) {
						beanClass.getMethod(createMethodName(pname),
								Short.class).invoke(object,
								Short.parseShort((String) map.get(pname)));
					}
					if (fieldType == Long.class) {
						beanClass
								.getMethod(createMethodName(pname), Long.class)
								.invoke(object,
										Long.parseLong((String) map.get(pname)));
					}
					if (fieldType == Float.class) {
						beanClass.getMethod(createMethodName(pname),
								Float.class).invoke(object,
								Float.parseFloat((String) map.get(pname)));
					}
					if (fieldType == Double.class) {
						beanClass.getMethod(createMethodName(pname),
								Double.class).invoke(object,
								Double.parseDouble((String) map.get(pname)));
					}
					if (fieldType == Character.class) {
						beanClass.getMethod(createMethodName(pname),
								Character.class).invoke(object,
								((String) map.get(pname)).charAt(0));
					}
					//
					if (fieldType == boolean.class) {
						beanClass.getMethod(createMethodName(pname),
								boolean.class).invoke(object,
								Boolean.parseBoolean((String) map.get(pname)));
					}
					if (fieldType == int.class) {
						beanClass.getMethod(createMethodName(pname), int.class)
								.invoke(object,
										Integer.parseInt((String) map
												.get(pname)));
					}
					if (fieldType == byte.class) {
						beanClass
								.getMethod(createMethodName(pname), byte.class)
								.invoke(object,
										Byte.parseByte((String) map.get(pname)));
					}
					if (fieldType == short.class) {
						beanClass.getMethod(createMethodName(pname),
								short.class).invoke(object,
								Short.parseShort((String) map.get(pname)));
					}
					if (fieldType == long.class) {
						beanClass
								.getMethod(createMethodName(pname), long.class)
								.invoke(object,
										Long.parseLong((String) map.get(pname)));
					}
					if (fieldType == float.class) {
						beanClass.getMethod(createMethodName(pname),
								float.class).invoke(object,
								Float.parseFloat((String) map.get(pname)));
					}
					if (fieldType == double.class) {
						beanClass.getMethod(createMethodName(pname),
								double.class).invoke(object,
								Double.parseDouble((String) map.get(pname)));
					}
					if (fieldType == char.class) {
						beanClass
								.getMethod(createMethodName(pname), char.class)
								.invoke(object,
										((String) map.get(pname)).charAt(0));
					}
				}
			}
		}
		return object;
	}

	public static String createMethodName(String fieldName) {
		return "set" + fieldName.trim().substring(0, 1).toUpperCase()
				+ fieldName.trim().toLowerCase().substring(1);
	}

	public static <T, V> void setBeanValue(T t, String fieldName, V value)
			throws NoSuchMethodException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {
		String MethodName = XBeanUtils.createMethodName(fieldName);
		Method method = t.getClass().getMethod(MethodName, value.getClass());
		method.invoke(t, value);
	}
	/**
	 * 根据request里的请求参数和值 自动给javaBean赋值
	 * 
	 **/
	// public static Object parseRequestToJavaBean(HttpServletRequest
	// request,Class beanClass) throws IllegalArgumentException,
	// SecurityException, IllegalAccessException, InvocationTargetException,
	// NoSuchMethodException, UnsupportedEncodingException{
	// Object object=null;
	// try {
	// object=beanClass.newInstance();
	// } catch (InstantiationException e) {
	// e.printStackTrace();
	// } catch (IllegalAccessException e) {
	// e.printStackTrace();
	// }
	// //获取所有表单名字
	// Enumeration<String> parameterNames=request.getParameterNames();
	// while(parameterNames.hasMoreElements()){
	// String pname=parameterNames.nextElement();
	// Field[] fields=beanClass.getDeclaredFields();
	// for(Field field:fields){
	// //找到对应的字段
	// if(field.getName().equals(pname)){
	// //获得该字段的类型
	// Class fieldType=field.getType();
	// //找到对应的set方法
	// if(fieldType==String.class){
	// String value=new
	// String(request.getParameter(pname).getBytes("iso8859-1"),"utf-8");
	// beanClass.getMethod(createMethodName(pname), String.class).invoke(object,
	// value);
	// }
	// if(fieldType==Boolean.class){
	// beanClass.getMethod(createMethodName(pname),Boolean.class).invoke(object,
	// Boolean.parseBoolean(request.getParameter(pname)));
	// }
	// if(fieldType==Integer.class){
	// beanClass.getMethod(createMethodName(pname),Integer.class).invoke(object,
	// Integer.parseInt(request.getParameter(pname)));
	// }
	// if(fieldType==Byte.class){
	// beanClass.getMethod(createMethodName(pname), Byte.class).invoke(object,
	// Byte.parseByte(request.getParameter(pname)));
	// }
	// if(fieldType==Short.class){
	// beanClass.getMethod(createMethodName(pname), Short.class).invoke(object,
	// Short.parseShort(request.getParameter(pname)));
	// }
	// if(fieldType==Long.class){
	// beanClass.getMethod(createMethodName(pname), Long.class).invoke(object,
	// Long.parseLong(request.getParameter(pname)));
	// }
	// if(fieldType==Float.class){
	// beanClass.getMethod(createMethodName(pname), Float.class).invoke(object,
	// Float.parseFloat(request.getParameter(pname)));
	// }
	// if(fieldType==Double.class){
	// beanClass.getMethod(createMethodName(pname), Double.class).invoke(object,
	// Double.parseDouble(request.getParameter(pname)));
	// }
	// if(fieldType==Character.class){
	// beanClass.getMethod(createMethodName(pname),
	// Character.class).invoke(object, request.getParameter(pname).charAt(0));
	// }
	// //
	// if(fieldType==boolean.class){
	// beanClass.getMethod(createMethodName(pname),boolean.class).invoke(object,
	// Boolean.parseBoolean(request.getParameter(pname)));
	// }
	// if(fieldType==int.class){
	// beanClass.getMethod(createMethodName(pname),int.class).invoke(object,
	// Integer.parseInt(request.getParameter(pname)));
	// }
	// if(fieldType==byte.class){
	// beanClass.getMethod(createMethodName(pname), byte.class).invoke(object,
	// Byte.parseByte(request.getParameter(pname)));
	// }
	// if(fieldType==short.class){
	// beanClass.getMethod(createMethodName(pname), short.class).invoke(object,
	// Short.parseShort(request.getParameter(pname)));
	// }
	// if(fieldType==long.class){
	// beanClass.getMethod(createMethodName(pname), long.class).invoke(object,
	// Long.parseLong(request.getParameter(pname)));
	// }
	// if(fieldType==float.class){
	// beanClass.getMethod(createMethodName(pname), float.class).invoke(object,
	// Float.parseFloat(request.getParameter(pname)));
	// }
	// if(fieldType==double.class){
	// beanClass.getMethod(createMethodName(pname), double.class).invoke(object,
	// Double.parseDouble(request.getParameter(pname)));
	// }
	// if(fieldType==char.class){
	// beanClass.getMethod(createMethodName(pname), char.class).invoke(object,
	// request.getParameter(pname).charAt(0));
	// }
	// }
	// }
	// }
	// return object;
	// }
	/**
	 * 获取bean的名字 小写的
	 * @param beanClass
	 * @return
	 */
	public static String getBeanName(Class beanClass){
		String name=beanClass.getName();
		name=name.substring(name.lastIndexOf(".")+1).toLowerCase();
		return name;
	}
	public static String[] getBeanFieldNames(Class beanClass){
		Field[] fields = beanClass.getFields();
		String[] names=new String[fields.length];
		for (int i = 0; i < names.length; i++) {
			names[i]=fields[i].getName();
		}
		return names;
	}
	/**
	 * class test{
	 * 	 List<Student> stus;
	 * }
	 * @param "stus"
	 * @return Student.class
	 */
	public static Class getListGenericType(Field field){
		Type mapMainType =field.getGenericType();
		 if (mapMainType instanceof ParameterizedType) {   
	            // 执行强制类型转换   
	            ParameterizedType parameterizedType = (ParameterizedType)mapMainType;   
	            // 获取基本类型信息，即Map   
	            Type basicType = parameterizedType.getRawType();   
	            System.out.println("基本类型为："+basicType);   
	            // 获取泛型类型的泛型参数   
	            Type[] types = parameterizedType.getActualTypeArguments();   
	            return (Class) types[0];
	     }
		 return null;
	}
	public static <T> T classNewInstance(Class<T> class1){
		try {
			Class<?> parentClass = class1.getDeclaringClass();
			if(parentClass==null){
				Object o=class1.newInstance();
				return class1.newInstance();
			}else{
				Constructor<?>[] c = class1.getDeclaredConstructors();
				T o = (T) c[0].newInstance(classNewInstance(parentClass));
				return o;
			}
		} catch (Exception e) {
			Log.e("classNewInstance", ""+e);
		}
		return null;
	}
}